package org.taobao.ibatiside.ui.wizard;

import java.beans.PropertyChangeEvent;

import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.beans.BeansObservables;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IPath;
import org.eclipse.datatools.modelbase.sql.query.QuerySelectStatement;
import org.eclipse.emf.databinding.EMFDataBindingContext;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wb.swt.ResourceManager;
import org.eclipse.wb.swt.SWTResourceManager;
import org.taobao.ibatiside.core.IbatisConstant;
import org.taobao.ibatiside.core.filemodel.FileProber;
import org.taobao.ibatiside.core.filemodel.IbatisConfigFile;
import org.taobao.ibatiside.ui.binding.ResourceAsStringConverter;
import org.taobao.ibatiside.ui.binding.ResourceIsReadyConverter;
import org.taobao.ibatiside.ui.util.MiscHelper;
import org.taobao.ibatiside.ui.util.WorkspaceUtil;

public class LocationAndDataObjectPage extends BatisCommonPage {
	private Button btnNewMap;
	private Text textConfigFile;
	private Group grpDataObject;
	private Combo comboMapList;
	private ComboViewer comboMappersViewer;
	private DataObjectGroup dataObjectGroup;
	public LocationAndDataObjectPage(String pageName) {
		super(pageName);
		setDescription("Configuration/SQLMap file location/Data Object class etc..");
		setTitle("Location/Class");
	}
	@Override
	public boolean canFlipToNextPage() {
		return model.getConfigurationFile() != null && model.getConfigurationFile().isAccessible()
				&&  model.getSqlmapFile() != null && model.getSqlmapFile().isAccessible()
				&&  (!model.getBeanNeedCreate() || (model.getBeanPath() != null && model.getBeanTemplate() != null)); 
		
	}
	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		super.propertyChange(evt);
		String pn = evt.getPropertyName();
		if (BatisSettingModel.K_CONFIGURATION_FILE.equals(pn)){
			updateMapList((IFile) evt.getNewValue());
		}else if (BatisSettingModel.K_DTP_STMT.equals(pn)){
			boolean show_bean_create = evt.getNewValue() == null || evt.getNewValue() instanceof QuerySelectStatement;
			grpDataObject.setVisible(show_bean_create);
		}else if (BatisSettingModel.K_SQLMAP_FILE.equals(pn)){
			IFile new_sqlmap_file = (IFile) evt.getNewValue();
			if (evt.getOldValue() == null && new_sqlmap_file != null){
				IPath  sqlmap_cls_path = WorkspaceUtil.getPackageFragementPath(new_sqlmap_file.getFullPath());
				comboMappersViewer.setSelection(new StructuredSelection(sqlmap_cls_path.toString()),true);
			}
		}
	}

	@Override
	public void doCreateControl(Composite parent) {
		Composite container = new Composite(parent, SWT.NULL);
		setControl(container);
		container.setLayout(new GridLayout(1, false));
		
		Group grpLocation = new Group(container, SWT.NONE);
		grpLocation.setText("Location");
		grpLocation.setLayout(new FormLayout());
		GridData gd_grpLocation = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gd_grpLocation.heightHint = 68;
		grpLocation.setLayoutData(gd_grpLocation);
		
		Label lblConfigurationFile = new Label(grpLocation, SWT.NONE);
		FormData fd_lblConfigurationFile = new FormData();
		fd_lblConfigurationFile.top = new FormAttachment(0, 3);
		fd_lblConfigurationFile.left = new FormAttachment(0);
		lblConfigurationFile.setLayoutData(fd_lblConfigurationFile);
		lblConfigurationFile.setText("Configuration File");
		
		Button btnChoose = new Button(grpLocation, SWT.NONE);
		btnChoose.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				IFile maybe_config_file = WorkspaceUtil.chooseFile(null, getShell());
				if (maybe_config_file != null){
					if (!maybe_config_file.isAccessible()){
						MessageDialog.openError(getShell(), "ERROR", "Can't access "+maybe_config_file.getLocation().toOSString());
						return;
					}
					if ("xml".equalsIgnoreCase(maybe_config_file.getFileExtension()) && FileProber.isIbatis2Config(maybe_config_file)){
						model.setConfigurationFile(maybe_config_file);
					}else{
						MessageDialog.openError(getShell(), "ERROR", maybe_config_file.getLocation().toOSString()+" is a not valid iBATIS configuration file!");
					}
				}
			}
		});
		FormData fd_btnChoose = new FormData();
		fd_btnChoose.left = new FormAttachment(0, 454);
		btnChoose.setLayoutData(fd_btnChoose);
		btnChoose.setText("Browse...");
		
		Label lblSqlmapFile = new Label(grpLocation, SWT.NONE);
		FormData fd_lblSqlmapFile = new FormData();
		fd_lblSqlmapFile.top = new FormAttachment(lblConfigurationFile, 12);
		fd_lblSqlmapFile.left = new FormAttachment(0, 10);
		lblSqlmapFile.setLayoutData(fd_lblSqlmapFile);
		lblSqlmapFile.setText("SQLMap File");
		
		comboMappersViewer = new ComboViewer(grpLocation, SWT.READ_ONLY);
		comboMappersViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				IStructuredSelection iss = (IStructuredSelection) event.getSelection();
				if (!iss.isEmpty()){
					String map_resource = (String) iss.getFirstElement();
					IFile map_file = WorkspaceUtil.findFile(model.getCurrentProject(), map_resource);
					if (map_file == null || !map_file.isAccessible()){
						MessageDialog.openError(getShell(), "ERROR", "Can not access "+map_resource+", please check it !");
						return;
					}
					model.setSqlmapFile(map_file);
				}
			}
		});
		comboMapList = comboMappersViewer.getCombo();
		FormData fd_comboMapList = new FormData();
		fd_comboMapList.left = new FormAttachment(lblSqlmapFile, 25);
		fd_comboMapList.top = new FormAttachment(lblSqlmapFile, -3, SWT.TOP);
		comboMapList.setLayoutData(fd_comboMapList);
		comboMappersViewer.setContentProvider(new ArrayContentProvider());
		comboMappersViewer.setLabelProvider(new LabelProvider());
		btnNewMap = new Button(grpLocation, SWT.NONE);
		fd_comboMapList.right = new FormAttachment(btnNewMap, -9);
		btnNewMap.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				String new_map_path = newMapPath();
				if (new_map_path != null){
					comboMappersViewer.setSelection(new StructuredSelection(new_map_path), true);
				}
			}
		});
		btnNewMap.setImage(ResourceManager.getPluginImage("org.taobao.ibatiside.ui", "icons/full/op16/new.png"));
		FormData fd_btnNewMap = new FormData();
		fd_btnNewMap.right = new FormAttachment(btnChoose, 120);
		fd_btnNewMap.top = new FormAttachment(btnChoose, 4);
		fd_btnNewMap.bottom = new FormAttachment(100, -10);
		fd_btnNewMap.left = new FormAttachment(btnChoose, 0, SWT.LEFT);
		btnNewMap.setLayoutData(fd_btnNewMap);
		btnNewMap.setText("Create New");
		
		textConfigFile = new Text(grpLocation, SWT.BORDER);
		textConfigFile.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
		textConfigFile.setEditable(false);
		FormData fd_textConfigFile = new FormData();
		fd_textConfigFile.right = new FormAttachment(68);
		fd_textConfigFile.top = new FormAttachment(lblConfigurationFile, 0, SWT.TOP);
		fd_textConfigFile.left = new FormAttachment(lblConfigurationFile, 6);
		textConfigFile.setLayoutData(fd_textConfigFile);
		
		grpDataObject = new Group(container, SWT.NONE);
		grpDataObject.setText("Data Object");
		grpDataObject.setLayout(new FillLayout(SWT.HORIZONTAL));
		grpDataObject.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		
		dataObjectGroup = new DataObjectGroup(grpDataObject, SWT.NONE,this);
		updateMapList(model.getConfigurationFile());
		
		//dataObjectGroup.setVisible(false);
	}
	protected String newMapPath() {
		IbatisConfigFile config = MiscHelper.convert2IbatisConfig(model.getConfigurationFile());
		if (config == null){
			MessageDialog.openWarning(getShell(),"Waring","Can't access "+model.getConfigurationFile());
			return null;
		}
		OverViewNewMapperWizard wizard = new OverViewNewMapperWizard(config.getConfigFile());
		wizard.setWindowTitle("Create new sqlmap for configuration "+config.getConfigFile().getName());
		WizardDialog dialog = new WizardDialog(getShell(), wizard);
		if (dialog.open() == WizardDialog.OK){
			IFile new_map_file = wizard.getSqlMapFile();
			if (new_map_file != null){
				updateMapList(model.getConfigurationFile());
				IPath new_map_clspath = WorkspaceUtil.getPackageFragementPath(new_map_file.getFullPath());
				return new_map_clspath.toString();
			}else{
				MessageDialog.openWarning(getShell(),"Waring","Can't create file ");
			}
		}
		return null;
	}
	private void updateMapList(IFile iFile) {
		if (iFile == null || !iFile.isAccessible()){		
			return;
		}
		comboMappersViewer.setInput(FileProber.getMapResources(iFile, IbatisConstant.VERSION_TWO));
	}
	@Override
	protected void doBinding(EMFDataBindingContext bindingContext) {
		//
		IObservableValue btnNewMapObserveEnabledObserveWidget = SWTObservables.observeEnabled(btnNewMap);
		IObservableValue modelConfigurationFileObserveValue = BeansObservables.observeValue(model, "configurationFile");
		UpdateValueStrategy strategy = new UpdateValueStrategy();
		strategy.setConverter(new ResourceIsReadyConverter());
		bindingContext.bindValue(btnNewMapObserveEnabledObserveWidget, modelConfigurationFileObserveValue, null, strategy);
		//
		IObservableValue grpDataObjectObserveEnabledObserveWidget = SWTObservables.observeEnabled(grpDataObject);
		bindingContext.bindValue(grpDataObjectObserveEnabledObserveWidget, modelConfigurationFileObserveValue, null, strategy);
		//
		IObservableValue comboMapListObserveEnabledObserveWidget = SWTObservables.observeEnabled(comboMapList);
		bindingContext.bindValue(comboMapListObserveEnabledObserveWidget, modelConfigurationFileObserveValue, null, strategy);
		//
		IObservableValue textConfigFileObserveTextObserveWidget = SWTObservables.observeText(textConfigFile);
		UpdateValueStrategy r2s_stragetry = new UpdateValueStrategy();
		r2s_stragetry.setConverter(new ResourceAsStringConverter());
		bindingContext.bindValue(textConfigFileObserveTextObserveWidget, modelConfigurationFileObserveValue, null, r2s_stragetry);
	}
}
